package com.zonski.jbots.desktop.game;

import java.awt.*;

import com.zonski.jbots.desktop.client.entity.*;
import com.zonski.jbots.desktop.client.tile.IndexedTileRenderer;
import com.zonski.jbots.desktop.client.ImageUtilities;
import com.zonski.jbots.desktop.client.RoomRenderer;
import com.zonski.jbots.desktop.client.PainterCanvas;
import com.zonski.jbots.client.IndexFactory;
import com.zonski.jbots.client.ConstantIndexFactory;
import com.zonski.jbots.client.FlipFlopIndexFactory;

import com.zonski.jbots.engine.Modes;

import com.zonski.jbots.game.JBotsConstants;
import com.zonski.jbots.game.entity.BombMind;

public final class JBotsRoomRendererFactory
{
    private Component component;
    private Toolkit toolkit;
    private ClassLoader classLoader;
    public JBotsRoomRendererFactory(Component component)
    {
        this.component = component;
        this.toolkit = component.getToolkit();
        this.classLoader = getClass().getClassLoader();
    }

    public RoomRenderer createRoomRenderer()
    {
        ClassLoader classLoader = this.getClass().getClassLoader();

        HashedEntityRendererFactory rf;
        rf = new HashedEntityRendererFactory();
        rf.setDefaultRenderer(new BoundsEntityRenderer(new Color(128, 255, 128)));


        Image n_bot = getImage("images/bots/n-red-bot.gif");
        Image n_bot_step1 = getImage("images/bots/n-red-bot-step1.gif");
        Image n_bot_step2 = getImage("images/bots/n-red-bot-step2.gif");
        Image n_bot_step3 = getImage("images/bots/n-red-bot-step3.gif");
        Image n_bot_step4 = getImage("images/bots/n-red-bot-step4.gif");

        Image ne_bot = getImage("images/bots/ne-red-bot.gif");
        Image ne_bot_step1 = getImage("images/bots/ne-red-bot-step1.gif");
        Image ne_bot_step2 = getImage("images/bots/ne-red-bot-step2.gif");
        Image ne_bot_step3 = getImage("images/bots/ne-red-bot-step3.gif");
        Image ne_bot_step4 = getImage("images/bots/ne-red-bot-step4.gif");

        Image n_comet = getImage("images/comet/n-red-comet.gif");
        Image ne_comet = getImage("images/comet/ne-red-comet.gif");
        Image n_comet_fly = getImage("images/comet/n-red-comet-fly.gif");

        Image n_bomb_bot_step1 = getImage("images/bombbot/n-red-bombbot-1.gif");
        Image n_bomb_bot_step2 = getImage("images/bombbot/n-red-bombbot-2.gif");
        Image n_bomb_bot_step3 = getImage("images/bombbot/n-red-bombbot-3.gif");

        Image bomb_1 = getImage("images/bomb/bomb.gif");
        Image bomb_2 = getImage("images/bomb/bomb-2.gif");

        Image battery = getImage("images/charger/battery.gif");
        Image capacity = getImage("images/charger/capacity.gif");

        Image n_turret = getImage("images/turret/n-turret.gif");
        Image ne_turret = getImage("images/turret/ne-turret.gif");

        Image pain_1 = getImage("images/pain/pain-1.gif");
        Image pain_2 = getImage("images/pain/pain-2.gif");
        Image pain_3 = getImage("images/pain/pain-3.gif");

        Image tank_1 = getImage("images/tank/tank-1.gif");
        Image tank_2 = getImage("images/tank/tank-2.gif");

        Image converter_1 = getImage("images/xvert/xvert1.gif");
        Image converter_2 = getImage("images/xvert/xvert2.gif");
        Image converter_3 = getImage("images/xvert/xvert3.gif");

        Image smasher_1 = getImage("images/smasher/smasher-1.gif");
        Image smasher_2 = getImage("images/smasher/smasher-2.gif");
        Image smasher_3 = getImage("images/smasher/smasher-3.gif");
        Image smasher_4 = getImage("images/smasher/smasher-4.gif");
        Image smasher_5 = getImage("images/smasher/smasher-5.gif");

        Image[][] walking_bot_images = ImageUtilities.createImages(
                new Image[]{n_bot_step4, n_bot_step3, n_bot, n_bot_step1, n_bot_step2},
                new Image[]{ne_bot_step4, ne_bot_step3, ne_bot, ne_bot_step1, ne_bot_step2},
                component);

        Image[][] standing_bot_images = ImageUtilities.createImages(
                new Image[]{n_bot},
                new Image[]{ne_bot},
                component);

        Image[][] comet_images = ImageUtilities.createImages(
                new Image[]{ne_comet, n_comet},
                new Image[]{ne_comet, n_comet},
                component);

        Image[][] comet_fly_images = ImageUtilities.createImages(
                new Image[]{n_comet_fly},
                new Image[]{n_comet_fly},
                component);

        Image[][] standing_bomb_bot_images = ImageUtilities.createImages(
                new Image[]{n_bomb_bot_step1},
                new Image[]{n_bomb_bot_step1},
                component);

        Image[][] walking_bomb_bot_images = ImageUtilities.createImages(
                new Image[]{n_bomb_bot_step2, n_bomb_bot_step1, n_bomb_bot_step3},
                new Image[]{n_bomb_bot_step2, n_bomb_bot_step1, n_bomb_bot_step3},
                component);

        Image[][] turret_images = ImageUtilities.createImages(
                new Image[]{n_turret}, new Image[]{ne_turret}, component
        );

        Image[][] walking_tank_images = ImageUtilities.createImages(
                new Image[]{tank_1, tank_2}, new Image[]{tank_1}, component
        );
        Image [][] standing_tank_images = ImageUtilities.createImages(
                new Image[]{tank_1}, new Image[]{tank_1}, component
        );

        Image[][] walking_converter_images = ImageUtilities.createImages(
                new Image[]{converter_1, converter_2, converter_3}, new Image[]{converter_1}, component
        );
        Image[][] standing_converter_images = ImageUtilities.createImages(
                new Image[]{converter_1}, new Image[]{converter_1}, component
        );

        Image[][] walking_smasher_images = ImageUtilities.createImages(
                new Image[]{smasher_5, smasher_4, smasher_1, smasher_2, smasher_3},
                new Image[]{smasher_1}, component
        );
        Image[][] standing_smasher_images = ImageUtilities.createImages(
                new Image[]{smasher_1},
                new Image[]{smasher_1},
                component
        );

        ImageEntityRenderer botRenderer = new ImageEntityRenderer(component);
        botRenderer.addFactory(Modes.NONE,
                new LayerImageFactory(standing_bot_images, 1,
                        new ConstantIndexFactory(0), this.component)
        );
        botRenderer.addFactory(Modes.WALKING,
                new LayerImageFactory(walking_bot_images, 1,
                    new FlipFlopIndexFactory(0, 4, 4), this.component)
        );
        rf.addRenderer(JBotsConstants.BOT, botRenderer);

        ImageEntityRenderer tankRenderer = new ImageEntityRenderer(component);
        tankRenderer.addFactory(Modes.NONE,
                new LayerImageFactory(standing_tank_images, 1, new ConstantIndexFactory(0), this.component)
        );
        tankRenderer.addFactory(Modes.WALKING,
                new LayerImageFactory(walking_tank_images, 1,
                        new FlipFlopIndexFactory(0, 1, 5), this.component)
        );
        rf.addRenderer(JBotsConstants.TANK_BOT, tankRenderer);

        ImageEntityRenderer converterRenderer = new ImageEntityRenderer(component);
        converterRenderer.addFactory(Modes.NONE,
                new LayerImageFactory(standing_converter_images, 1, new ConstantIndexFactory(0), this.component));
        converterRenderer.addFactory(Modes.WALKING,
                new LayerImageFactory(walking_converter_images, 1, new FlipFlopIndexFactory(0, 2, 2), this.component));
        rf.addRenderer(JBotsConstants.CONVERTER_BOT, converterRenderer);

        ImageEntityRenderer smasherRenderer = new ImageEntityRenderer(component);
        smasherRenderer.addFactory(Modes.NONE,
                new LayerImageFactory(standing_smasher_images, 1, new ConstantIndexFactory(0), this.component));
        smasherRenderer.addFactory(Modes.WALKING,
                new LayerImageFactory(walking_smasher_images, 1, new FlipFlopIndexFactory(0, 4, 2), this.component));
        rf.addRenderer(JBotsConstants.BABY_BOT, smasherRenderer);

        ImageEntityRenderer painRenderer = new ImageEntityRenderer(component);
        painRenderer.addFactory(Modes.DEAD,
                new LayerImageFactory(new Image[][]{{pain_1, pain_2, pain_3}}, 1,
                        new FlipFlopIndexFactory(0, 2, 2), this.component));
        rf.addRenderer(JBotsConstants.PAIN, painRenderer);

        Image rock = getImage("images/blocks/purple-circle.gif");
        ImageEntityRenderer rockRenderer = new ImageEntityRenderer(component);
        rockRenderer.addFactory(Modes.NONE,
                new ImageFactory(new Image[][]{{rock}}, new ConstantIndexFactory(0))
        );
        rf.addRenderer("Rock", rockRenderer);

        Image temprock = getImage("images/blocks/red-circle.gif");
        ImageEntityRenderer temprockRenderer = new ImageEntityRenderer(component);
        temprockRenderer.addFactory(Modes.NONE,
                new ImageFactory(new Image[][]{{temprock}}, new ConstantIndexFactory(0))
        );
        rf.addRenderer(JBotsConstants.TEMP_ROCK, temprockRenderer);

        Image treerock = getImage("images/blocks/tree.gif");
        ImageEntityRenderer treerockRenderer = new ImageEntityRenderer(component);
        treerockRenderer.addFactory(Modes.NONE,
                new ImageFactory(new Image[][]{{treerock}}, new ConstantIndexFactory(0))
        );
        rf.addRenderer(JBotsConstants.TREE, treerockRenderer);

        ImageEntityRenderer batteryRenderer = new ImageEntityRenderer(component);
        batteryRenderer.addFactory(Modes.NONE,
                new ImageFactory(new Image[][]{{battery}}, new ConstantIndexFactory(0))
        );
        rf.addRenderer(JBotsConstants.CHARGE, batteryRenderer);

        ImageEntityRenderer capacityRenderer = new ImageEntityRenderer(component);
        capacityRenderer.addFactory(Modes.NONE,
                new ImageFactory(new Image[][]{{capacity}}, new ConstantIndexFactory(0)));
        rf.addRenderer(JBotsConstants.CAPACITY, capacityRenderer);

        ImageEntityRenderer bombRenderer = new ImageEntityRenderer(component);
        bombRenderer.addFactory(Modes.NONE,
                new ImageFactory(new Image[][]{{bomb_1}}, new ConstantIndexFactory(0))
        );
        bombRenderer.addFactory(BombMind.PRE_EXPLOSION,
                new ImageFactory(new Image[][]{{bomb_1, bomb_2}}, new FlipFlopIndexFactory(0, 1, 1))
        );
        rf.addRenderer(JBotsConstants.BOMB, bombRenderer);

        ImageEntityRenderer cometRenderer = new ImageEntityRenderer(component);
        cometRenderer.addFactory(Modes.NONE,
                new LayerImageFactory(comet_images, 1, new FlipFlopIndexFactory(0, 1, 1), this.component)
        );
        cometRenderer.addFactory(Modes.WALKING,
                new LayerImageFactory(comet_fly_images, 1, new ConstantIndexFactory(0), this.component)
        );
        rf.addRenderer("Comet", cometRenderer);

        ImageEntityRenderer turretRenderer = new ImageEntityRenderer(component);
        turretRenderer.addFactory(Modes.NONE,
                new LayerImageFactory(turret_images, 1, new ConstantIndexFactory(0), this.component)
        );
        rf.addRenderer(JBotsConstants.TURRET_BOT, turretRenderer);
        /*
        ImageEntityRenderer eggRenderer = new ImageEntityRenderer(component);
        eggRenderer.addFactory(Modes.NONE,
                new ImageFactory(new Image[][]{{large_egg}}, new ConstantIndexFactory(0))
                );
                */
        rf.addRenderer(JBotsConstants.EGG, new EggRenderer());

        ImageEntityRenderer bombBotRenderer = new ImageEntityRenderer(component);
        bombBotRenderer.addFactory(Modes.NONE,
                new LayerImageFactory(standing_bomb_bot_images, 1, new ConstantIndexFactory(0), this.component));
        bombBotRenderer.addFactory(Modes.WALKING,
            new LayerImageFactory(walking_bomb_bot_images, 1,
                new FlipFlopIndexFactory(0, 2, 4), this.component));
        rf.addRenderer(JBotsConstants.BOMB_BOT, bombBotRenderer);


        // tile renderer
        Image tile1 = getImage("images/tiles/metal-1.gif");
        Image tile2 = getImage("images/tiles/metal-2.gif");
        Image tile3 = getImage("images/tiles/metal-3.gif");
        Image tile4 = getImage("images/tiles/grass-1.gif");
        Image tile5 = getImage("images/tiles/s-grass-1.gif");
        Image tile6 = getImage("images/tiles/w-grass-1.gif");
        Image tile7 = getImage("images/tiles/n-grass-1.gif");
        Image tile8 = getImage("images/tiles/e-grass-1.gif");
        Image[] tiles = new Image[]{tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8};

        rf.addRenderer("Explosion", new ExplosionRenderer());
        rf.addRenderer(JBotsConstants.RECHARGE, new ChargerRenderer(
                getImage("images/charger/active.gif"), getImage("images/charger/inactive.gif")
        ));

        // a nasty little kludge
        if(this.component instanceof PainterCanvas)
        {
            ((PainterCanvas)this.component).setPlayerImage(this.getImage("images/console/brain.gif"));
        }

        return new RoomRenderer(rf, new IndexedTileRenderer(tiles, this.component));
    }

    private Image getImage(String path)
    {
        return this.toolkit.createImage(this.classLoader.getResource(path));
    }
}
